home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_mac.hqx / SRGP port to 5.0 (compressed) / SRGP_SPHIGS Root / MacSPHIGS / sph_refresh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  8.1 KB  |  334 lines

  1. #include "HEADERS.h"
  2. #include "sphigslocal.h"
  3.  
  4. #include "sph_refresh.proto.h"
  5. static void PREPARE_FOR_DRAWING(void);
  6. static void TERMINATE_DRAWING(void);
  7. static void RefreshOneView(int);
  8. static void WHITEWASH_RECT(srgp__rectangle);
  9. static void PERFORM_REFRESH(void);
  10.  
  11.  
  12. static boolean double_buffer_flag = FALSE;
  13. static int cur_screen_width, cur_screen_height;
  14. static int buffer_canvas;
  15.  
  16.  
  17.  
  18. void SPH_setDoubleBufferingFlag (boolean flag)
  19. {
  20.    if (flag == double_buffer_flag)
  21.       return;
  22.       
  23.    if (flag) {
  24.       /* USER IS TURNING ON DOUBLE BUFFERING */
  25.       /* Allocate an SRGP canvas */
  26.       SRGP_inquireCanvasSize (0, &cur_screen_width, &cur_screen_height);
  27.       buffer_canvas = SRGP_createCanvas (cur_screen_width, cur_screen_height);
  28.       /* Initialize to copy of current screen */
  29.       SRGP_useCanvas (buffer_canvas);
  30.       SRGP_copyPixel (0, SRGP_inquireCanvasExtent(0), SRGP_defPoint(0,0));
  31.    }
  32.    else {
  33.       /* USER IS DISABLING DOUBLE BUFFERING */
  34.       /* Deallocate the canvas */
  35.       SRGP_deleteCanvas (buffer_canvas);
  36.    }
  37.    
  38.    double_buffer_flag = flag;
  39. }
  40.  
  41. static void PREPARE_FOR_DRAWING (void)
  42. {
  43.    SRGP_useCanvas (double_buffer_flag ? buffer_canvas : 0);
  44. }
  45.  
  46. #define BUFFER_TO_SCREEN   TERMINATE_DRAWING
  47.  
  48. static void TERMINATE_DRAWING (void)
  49. {
  50.    if (double_buffer_flag) {
  51.       SRGP_useCanvas (0);
  52.       SRGP_copyPixel (buffer_canvas, 
  53.               SRGP_inquireCanvasExtent(0), SRGP_defPoint(0,0));
  54.    }
  55. }
  56.  
  57.  
  58. /** REFRESH ONE VIEW
  59. Should be called only if a redraw (at least) is needed!
  60.  
  61. IF wireframe rendering (raw or otherwise):
  62.     full retraversal is performed
  63. ELSE:
  64.    IF view has obsolete object list:
  65.     full retraversal
  66.    ELSE IF view has obsolete PDC vertex list:
  67.     PDC vertices are recalculated from the UVN list
  68.    ELSE 
  69.     Redrawing *only* is performed
  70.     
  71. This function resets the obsolescence flags in the view table!
  72. **/
  73.  
  74. static void
  75. RefreshOneView (int vi)
  76. {
  77.    register root_header *root;
  78.    boolean do_retraverse = FALSE;
  79.  
  80.    currentViewIndex = vi;
  81.    currentViewSpec = &(SPH_viewTable[currentViewIndex]);
  82.    currentRendermode = currentViewSpec->rendermode;
  83.  
  84.    /* Ignore this view if no roots are posted to it, or it's disabled */
  85.    if ((currentViewSpec->lowestOverlapNetwork == NULL) || 
  86.        (currentViewSpec->currently_disabled))
  87.               return;
  88.    
  89.    if ((currentViewSpec->obsolete_object_list) || 
  90.        (currentRendermode==WIREFRAME_RAW))
  91.       do_retraverse = TRUE;
  92.  
  93.  
  94.    /* Clear the viewport area */
  95.    SRGP_setClipRectangle (currentViewSpec->pdc_viewport);
  96.    SRGP_setFillStyle (SOLID);
  97.    SRGP_setColor (currentViewSpec->background_color);
  98.    SRGP_fillRectangle (currentViewSpec->pdc_viewport);
  99.    
  100.    if (do_retraverse) {
  101.       if (currentRendermode > WIREFRAME_RAW)   
  102.          OBJECT__init (currentViewSpec);
  103.       for
  104.          (root = currentViewSpec->lowestOverlapNetwork;
  105.           root != NULL;
  106.           root = root->nextHigherOverlapRoot)
  107.         SPH__traverse_network_for_display (currentViewSpec, root);
  108.    }
  109.  
  110.  
  111.    /* IF rendermode IS NOT RAW, WE NEED TO PROCESS THE OBJECTS. */
  112.    if (currentRendermode > WIREFRAME_RAW) {
  113.       if (do_retraverse) 
  114.          OBJECT__process (currentViewSpec);
  115.       else if (currentViewSpec->obsolete_pdc_vertices)
  116.          SPH__generate_pdc_vertices (currentViewSpec);
  117.       OBJECT__drawAll (currentViewSpec);
  118.    }
  119.  
  120.    /* TELL SRGP TO REFRESH SCREEN  (no-op unless X11) */
  121.    SRGP_refresh();
  122.    
  123.    /* RESET THE FLAGS */
  124.    currentViewSpec->obsolete_object_list = 
  125.       currentViewSpec->obsolete_pdc_vertices = FALSE;
  126. }
  127.  
  128.  
  129. static void
  130. WHITEWASH_RECT (srgp__rectangle r)
  131. {
  132.    SRGP_setClipRectangle (r);
  133.    SRGP_setFillStyle (SOLID);
  134.    SRGP_setColor (SRGP_WHITE);
  135.    SRGP_fillRectangle (r);
  136. }
  137.  
  138.  
  139.  
  140.  
  141. /** PERFORM REFRESH
  142. Only refreshes views that actually need to be redrawn or retraversed due to
  143. changes in objects or in the view specification
  144. **/
  145. static void
  146. PERFORM_REFRESH (void)
  147. {
  148.    register vi;
  149.    register view_spec *v;
  150.  
  151.    for (vi=0; vi <= MAX_VIEW_INDEX; vi++) {
  152.       v = &(SPH_viewTable[vi]);
  153.       if ((v->obsolete_object_list) || (v->obsolete_pdc_vertices))
  154.          RefreshOneView (vi);
  155.    }
  156. }
  157.  
  158.  
  159.  
  160. /*!*/
  161. void
  162. SPH_setImplicitRegenerationMode (int mode)
  163. {
  164.    if (mode == SPH_implicit_regeneration_mode)
  165.       return;
  166.       
  167.    if (mode==ALLOWED)
  168.      PERFORM_REFRESH();
  169.      
  170.    SPH_implicit_regeneration_mode = mode;
  171. }
  172.  
  173.  
  174. /** REGENERATE SCREEN
  175. Called by the application, typically when it has turned off 
  176.    implicit regeneration.
  177. Thus, we can't assume we're just repairing screen damage!
  178. But it does not retraverse or recompute PDCs
  179.    unless a true data change occurred, so it is efficient.
  180. **/
  181. void
  182. SPH_regenerateScreen (void)
  183. {
  184.    register vi;
  185.  
  186.    PREPARE_FOR_DRAWING();
  187.    for (vi=0; vi <= MAX_VIEW_INDEX; vi++)
  188.        RefreshOneView (vi);
  189.    TERMINATE_DRAWING();
  190.  
  191. }
  192.  
  193.  
  194. /** REPAINT SCREEN
  195. Called  when we are told by the window manager that an
  196.    update should occur to handle damage.
  197. ASSUMES no data change has taken place since screen last painted.
  198. Very efficient if double buffering happens to be on.
  199. CURRENTLY NOT INSTALLED.  Moreover, it's not needed when backing store is on.
  200. **/
  201. void
  202. SPH__repaintScreen (void)
  203. {
  204.    if (double_buffer_flag)
  205.       BUFFER_TO_SCREEN();
  206.    else
  207.       SPH_regenerateScreen();
  208. }
  209.  
  210.  
  211.  
  212. /*!*/
  213. void
  214. SPH_setRenderingMode (int viewindex, int value)
  215. {
  216.    SPH_viewTable[viewindex].rendermode = value;
  217.    
  218.    SPH_viewTable[viewindex].obsolete_object_list = TRUE;
  219.    if (SPH_implicit_regeneration_mode == ALLOWED) {
  220.       PREPARE_FOR_DRAWING();
  221.       RefreshOneView (viewindex);
  222.       TERMINATE_DRAWING();
  223.    }
  224. }
  225.  
  226.  
  227.  
  228.  
  229. /*!*/
  230. void
  231. SPH__refresh_structure_close (int structID)
  232. {
  233.    register int v;
  234.  
  235.    PREPARE_FOR_DRAWING();
  236.    for (v=0; v<=MAX_VIEW_INDEX; v++)
  237.      if (TestBit(SPH_viewTable[v].descendent_list, structID)) {
  238.         SPH_viewTable[v].obsolete_object_list = TRUE;
  239.         if (SPH_implicit_regeneration_mode == ALLOWED)
  240.            RefreshOneView (v);
  241.      }
  242.    TERMINATE_DRAWING();
  243. }
  244.       
  245.  
  246.  
  247.  
  248. /*!*/
  249. void SPH__refresh_post (int view)
  250. {
  251.    PREPARE_FOR_DRAWING();
  252.    SPH_viewTable[view].obsolete_object_list = TRUE;
  253.    if (SPH_implicit_regeneration_mode == ALLOWED)
  254.       RefreshOneView (view);
  255.    TERMINATE_DRAWING();
  256. }
  257.  
  258.  
  259.  
  260.  
  261. /** Refreshing after an unpost
  262. If the view no longer has any posted members, do a whitewash!
  263. **/
  264. void SPH__refresh_unpost (int view)
  265. {
  266.    PREPARE_FOR_DRAWING();
  267.    if (SPH_viewTable[view].highestOverlapNetwork == NULL)
  268.       WHITEWASH_RECT (SPH_viewTable[view].pdc_viewport);
  269.    else {
  270.       SPH_viewTable[view].obsolete_object_list = TRUE;
  271.       if (SPH_implicit_regeneration_mode == ALLOWED)
  272.          RefreshOneView (view);
  273.    }
  274.    TERMINATE_DRAWING();
  275. }
  276.  
  277.  
  278.  
  279. /** Refreshing after a viewport change
  280. Should we whitewash the area that is occupied by the current
  281. viewport for this view?
  282.  Only if:
  283.           1) There is at least one structure posted to the view.
  284.    AND  2) The intersection of the current vp and the new vp is NOT
  285.            equal to the current vp.
  286.            
  287.  LATER: we will have to repair damage done to overlapping
  288.              innocent-bystander views.
  289. **/
  290. void SPH__refresh_viewport_change (int viewIndex, srgp__rectangle old_viewport_rect)
  291. {
  292.    srgp__rectangle intersection;
  293.    
  294.    PREPARE_FOR_DRAWING();
  295.    if (GEOM_computeRectIntersection(old_viewport_rect, 
  296.                            SPH_viewTable[viewIndex].pdc_viewport,
  297.                         &intersection))
  298.        /* GEOM SAYS THEY DO INTERSECT */
  299.        if ( ! memcmp(&intersection,&old_viewport_rect, sizeof(srgp__rectangle))) 
  300.           /* AH!  The intersection is equal to the original viewport. */
  301.           /* Don't whitewash! */
  302.           goto dorefresh_vpc;
  303.    
  304.    /* Perform the whitewash! */
  305.    WHITEWASH_RECT (old_viewport_rect);
  306.        
  307.  dorefresh_vpc:
  308.    SPH_viewTable[viewIndex].obsolete_object_list = TRUE;
  309.    if (SPH_implicit_regeneration_mode == ALLOWED)
  310.       RefreshOneView (viewIndex);
  311.       
  312.    TERMINATE_DRAWING();
  313. }
  314.  
  315.  
  316. void SPH_disableView (int v)
  317. {
  318.   if (SPH_viewTable[v].currently_disabled)
  319.      return;
  320.      
  321.   WHITEWASH_RECT (SPH_viewTable[v].pdc_viewport);
  322.   SPH_viewTable[v].currently_disabled = TRUE;
  323. }
  324.  
  325. void SPH_enableView (int v)
  326. {
  327.   if ( ! SPH_viewTable[v].currently_disabled)
  328.      return;
  329.      
  330.   SPH_viewTable[v].currently_disabled = FALSE;
  331.   SPH__refresh_viewport_change (v, SPH_viewTable[v].pdc_viewport);
  332. }
  333.  
  334.